#pragma once
#include "kernel_operator.h"
#include <cstdint>
#define INDEX_MOVE_LEFT(index)                                                 \
  for (auto i = index; i < size_ - 1; ++i) {                                   \
    data_[i] = data_[i + 1];                                                   \
  }                                                                            \
  size_--;

#define INDEX_MOVE_RIGHT(index)                                                \
  for (auto i = index + 1; i <= size_; ++i) {                                  \
    data_[i] = data_[i - 1];                                                   \
  }                                                                            \
  size_++;

template <typename T> struct SimpleList {
  int64_t size_ = 0;
  __gm__ T *data_ = nullptr;
  __aicore__ inline SimpleList() : size_(0) {}
  __aicore__ inline void init(GM_ADDR workspace) {
    data_ = (__gm__ T *)workspace;
    size_ = 0;
  }
  __aicore__ inline void push_front(T v) {
    INDEX_MOVE_RIGHT(0);
    data_[0] = v;
  }
  __aicore__ inline T pop_front() {
    auto ret = data_[0];
    INDEX_MOVE_LEFT(0);
    return ret;
  }
  __aicore__ inline void push_back(T v) { data_[size_++] = v; }
  __aicore__ inline T pop_back() { return data_[--size_]; }
  __aicore__ inline bool empty() { return size_ == 0; }
  __aicore__ inline void insert(int64_t index, T v) {
    INDEX_MOVE_RIGHT(index);
    data_[index] = v;
  }
  __aicore__ inline void remove(int64_t index) { INDEX_MOVE_LEFT(index); }
  __aicore__ inline void clear() { size_ = 0; }
};